package com.valsong.sandbox.mock.classloader;

import lombok.extern.slf4j.Slf4j;


/**
 * ComposeClassLoader
 * 使用ComposeClassLoader将ModuleJarClassLoader和ContextClassLoader当做一个class loader来使用
 *
 * @author Val Song
 */
@Slf4j
public class ComposeClassLoader extends ClassLoader {

    /**
     * groovy相关的class的package前缀
     */
    public static final String[] GROOVY_PACKAGE_PREFIX = {"groovy",
            "groovyjarjarantlr",
            "groovyjarjarantlr4",
            "groovyjarjarasm",
            "groovyjarjarpicocli",
            "org.apache.groovy",
            "org.codehaus.groovy"};

    /**
     * 仅仅加载groovy相关的class
     */
    private ClassLoader moduleJarClassLoader;

    private ClassLoader contextClassLoader;

    public ComposeClassLoader(ClassLoader moduleJarClassLoader, ClassLoader contextClassLoader) {
        super(null);
        this.moduleJarClassLoader = moduleJarClassLoader;
        this.contextClassLoader = contextClassLoader;
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        //使用moduleJarClassLoader来加载与groovy相关的class
        try {
            for (String prefix : GROOVY_PACKAGE_PREFIX) {
                if (name.startsWith(prefix)) {
                    Class<?> clazz = moduleJarClassLoader.loadClass(name);
                    log.debug("loadClass name:[{}] clazz:[{}] classLoader:[{}]", name, clazz, moduleJarClassLoader);
                    return clazz;
                }
            }
        } catch (ClassNotFoundException e) {
        }

        try {
            Class<?> clazz = contextClassLoader.loadClass(name);
            log.debug("loadClass name:[{}] clazz:[{}] classLoader:[{}]", name, clazz, contextClassLoader);
            return clazz;
        } catch (ClassNotFoundException e) {
        }

        throw new ClassNotFoundException(String.format("Can't find class:[%s] by moduleJarClassLoader:[%s] and contextClassLoader:[%s]",
                name, moduleJarClassLoader, contextClassLoader));

    }

}
